package com.quotientintelligence.caftrak.shared;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.jdo.annotations.Element;

import java.util.ArrayList;
import java.util.List;

import com.quotientintelligence.caftrak.shared.Substance;
import com.quotientintelligence.caftrak.shared.Substance.ActiveIng;
import com.quotientintelligence.caftrak.shared.Substance.MUnits;
import com.google.appengine.api.datastore.Key;


@PersistenceCapable
public class Drink {
	
	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private Key _key;

	@Persistent
	public String Name;
	
	@Persistent
	public float Volume;
	
	@Persistent
	@Element(dependent = "true") 
	private List<Substance> Ingredients;
	
	public Drink(){Ingredients = new ArrayList<Substance>();}
	public Drink(String name) {
		this();
		this.Name = name;
	}
	public Drink(String name, float volume){
		this(name);
		this.Volume = volume;
	}
	
	public List<Substance> getIngredients()
	{return Ingredients;}
	
	public void addIngredient(Substance s)
	{
		addIngredientIfNotPresent(s);
	}
	public void addIngredient(Substance s, boolean replace)
	{
		if (replace)
			addOrReplaceIngredient(s);
		else
			addOrExtendIngredient(s);
	}
	public boolean addIngredientIfNotPresent(Substance s)
	{		
		boolean hadIt = hasIngredient(s);
		if(!hadIt)
			Ingredients.add(s);
		return hadIt;	
	}
	
	public void addOrReplaceIngredient(Substance s)	{
		if(!addIngredientIfNotPresent( s))	{			
			Ingredients.remove(findIngredient(s));
			Ingredients.add(s);
		}
	}
	
	public void addOrExtendIngredient(Substance s)	{
		if(!addIngredientIfNotPresent( s)) 	{			
			Substance oldS = findIngredient(s);
			Ingredients.remove(oldS);
			oldS.set_quantity(oldS.get_quantity() + s.get_quantity());
			Ingredients.add(oldS);
		}	
	}
	
	public boolean hasIngredient(Substance s)	{
		if( Ingredients.contains(s))
			return true;
		else {
			Substance isFound = findIngredient(s);
			return (isFound != null);
		}
	}
	public boolean hasIngredient(ActiveIng ai)	{			
		Substance isFound = findIngredient(ai);
		return (isFound != null);
	}

	private Substance findIngredient(Substance s2find)	{
		Substance findMe = null;
		for (Substance ing:Ingredients)	{
			if (ing.get_substanceType() == s2find.get_substanceType())	{
				findMe = ing;
				break;
			}
		}	
		return findMe;
	}
	
	private Substance findIngredient(ActiveIng ai)	{
		Substance findMe = null;
		for (Substance ing:Ingredients)	{
			if (ai.equals(ing.get_substanceType()))	{
				findMe = ing;
				break;
			}
		}	
		return findMe;
	}

	public float getIngredientRatio(ActiveIng ing)
	{
		Substance sub = this.findIngredient(ing);
		if(sub != null)
			return sub.get_quantity()/this.Volume;
		else return 0;
	}
	
	public float getIngredientRatio(ActiveIng ing, MUnits m)
	{
		Substance sub = this.findIngredient(ing);
		if(sub != null)
			return sub.get_quantity(m)/this.Volume;
		else return 0;
	}
	
	public void set_key(Key _key) {
		this._key = _key;
	}

	public Key get_key() {
		return _key;
	}
}
